#	snippet vivado_non_project_step0 "Define output directory location" !b
#	# step0 : Define output directory location
#	set PROJECT_PATH  ${3:/home/wj/tmp/}
#	set outputDir ./synth_tmp
#	
#	set top_module_name ${1:module_name}
#	set_part ${2:xc7z020clg400-1}
#	file mkdir $outputDir
#	
#	read_verilog \$PROJECT_PATH/path/$1.v
#	endsnippet
#	
#	snippet vivado_non_project_step1 "Setup design sources and constraints" !b
#	# step1 : Setup design sources and constraints
#	
#	# read_verilog {name1.v name2.v}
#	# read_verilog [ glob ../hdl/*.v ]
#	# read_xdc ./pin.xdc
#	# read_vhdl
#	# read_edif
#	# read_ip(.xci or .xco)
#	# read_bd
#	endsnippet
#	
#	snippet vivado_non_project_step2 "Run synthesis, report utilization" !b
#	# step2 : Run synthesis, report utilization and timing estimates, write checkpoint design.
#	synth_design -top ${1:top_module_name}
#	# write_checkpoint -force $outputDir/post_synth
#	# report_timing_summary -file $outputDir/post_synth_timing_summary.rpt
#	# report_power -file $outputDir/post_synth_power.rpt
#	# report_clock_interaction -delay_type min_max -file $outputDir/post_synth_clock_interaction.rpt
#	# report_high_fanout_nets -fanout_greater_than 200 -max_nets 50 -file $outputDir/post_synth_high_fanout_nets.rpt
#	endsnippet
#	
#	snippet vivado_non_project_step3 "Run placement and logic optimization" !b
#	# step3 : Run placement and logic optimization, report utilization and timing estimates, write checkpoint design.
#	opt_design
#	place_design
#	phys_opt_design
#	# write_checkpoint -force $outputDir/post_place
#	# report_timing_summary -file $outputDir/post_place_timing_summary.rpt
#	endsnippet
#	
#	snippet vivado_non_project_step4 "Run router" !b
#	# step4 : Run router, report actual utilization and timing, write checkpoint design, run drc, write verilog and xdc out.
#	route_design
#	# write_checkpoint -force $outputDir/post_route
#	# report_timing_summary -file $outputDir/post_route_timing_summary.rpt
#	# report_timing -max_paths 100 -path_type summary -slack_lesser_than 0 -file $outputDir/post_route_setup_timing_violations.rpt
#	# report_clock_utilization -file $outputDir/clock_util.rpt
#	# report_utilization -file $outputDir/post_route_util.rpt
#	# report_power -file $outputDir/post_route_power.rpt
#	# report_drc -file $outputDir/post_imp_drc.rpt
#	# write_verilog -force $outputDir/bft_impl_netlist.v
#	# write_xdc -no_fixed_only -force $outputDir/bft_impl.xdc
#	endsnippet
#	
#	snippet vivado_non_project_step5 "Generate a bitstream" !b
#	# step5 : Generate a bitstream.
#	write_debug_probes -force $outputDir/$top_module_name.ltx
#	write_bitstream -force $outputDir/$top_module_name.bit
#	endsnippet

snippet build_version "create a version information file"
# 生成FPGA项目版本相关信息。项目gitignore里需要过滤掉version.vh文件
# vivado项目可以在SYNTHESIS阶段, tcl.pre前调用此tcl脚本，自动生成版本文件

# 1. 手动修改软件版本号
# 2. 自动获取git log时间
# 3. 自动获取git commit hash

# 指定项目路径
set project_dir /home/wj/work/CaptureCard/

# 指定文件名
set version_file \$project_dir/hdl/version.vh

# v0.34 
set version 0.34

# 获取git log 时间: 格式20240319
set output [exec git --git-dir=\$project_dir/.git log -1 --pretty=format:%cs --date=short]
regexp {(\d{4})-(\d{2})-(\d{2})} \$output -> year month day
set git_date "$year$month$day"

# 获取git commit 前7个字符
set git_hash_value [exec git --git-dir=\$project_dir/.git log --pretty=format:%h -1]

# 获取版本号
set fileid [open \$version_file w+]
seek \$fileid 0 start

puts \$fileid "\`define VERSION       \"$version\" "
puts \$fileid "\`define LOG_DATE      \"$git_date\"   "
puts \$fileid "\`define HASH_VALUE    \"$git_hash_value\" "
close \$fileid

endsnippet

snippet build_vivado_project "build vivado project"
# set argv [list /home/wj/tmp/project_1 xc7z100ffg900-2 main]
# source /path/name.tcl

if { [llength $argv ] == 3 } {
    set project_path [lindex $argv 0]
    set device_type [lindex $argv 1]
    set project_name [lindex $argv 2]
} else {
    puts "Some parameters are missing and the project is created with default parameters"

    set script_path [ file dirname [ file normalize [ info script ] ] ]
    set script_parent_path [ file dirname $script_path ]

    set project_path $script_parent_path
    set device_type xc7z100ffg900-2
	set project_name [file tail $script_path]
}


if {[file exists $project_path/vivado/$project_name]} {
    # 删除目录
    file delete -force $project_path/vivado/$project_name
    puts "目录已成功删除。"
}

# 创建工程
create_project $project_name $project_path/vivado/$project_name -part $device_type

# 加载开发板zynq默认配置
set bd_name arm9
source $::env(HOME)/SynologyDrive/board/AX7Z100B/zynq_config.tcl
regenerate_bd_layout
generate_target all [get_files  $project_path/vivado/$project_name/$project_name.srcs/sources_1/bd/$bd_name/${bd_name}.bd]

make_wrapper -files [get_files $project_path/vivado/$project_name/$project_name.srcs/sources_1/bd/$bd_name/${bd_name}.bd] -top
add_files -norecurse           $project_path/vivado/$project_name/$project_name.srcs/sources_1/bd/$bd_name/hdl/${bd_name}_wrapper.v

# 添加文件
# add_files -fileset sources_1 [ glob $project_path/hdl/*.v ]
set_property verilog_define "AAA BBB" [current_fileset]

# 添加ip

proc generate_sim_files {project_path project_name ip_name} {
    generate_target all [get_files  $project_path/vivado/$project_name/$project_name.srcs/sources_1/ip/$ip_name/$ip_name.xci]
    export_ip_user_files -of_objects [get_files $project_path/vivado/$project_name/$project_name.srcs/sources_1/ip/$ip_name/$ip_name.xci] -no_script -sync -force -quiet
    # create_ip_run [get_files -of_objects [get_fileset sources_1] $project_path/vivado/$project_name/$project_name.srcs/sources_1/ip/$ip_name/$ip_name.xci]
    export_simulation -of_objects [get_files $project_path/vivado/$project_name/$project_name.srcs/sources_1/ip/$ip_name/$ip_name.xci] \
                      -directory $project_path/vivado/$project_name/$project_name.ip_user_files/sim_scripts \
                      -ip_user_files_dir $project_path/vivado/$project_name/$project_name.ip_user_files \
                      -ipstatic_source_dir $project_path/vivado/$project_name/$project_name.ip_user_files/ipstatic \
                      -use_ip_compiled_libs -force -quiet
}
foreach ip_name [ get_ips ] {
    generate_sim_files $project_path $project_name $ip_name
}
# 添加xdc. 使用import可以将文件复制到工程目录下
add_files -fileset constrs_1 -norecurse [ glob $project_path/constraint/*.xdc ]

import_files -fileset constrs_1 $project_path/debug/axi_gpio.xdc

# 编译
launch_runs synth_1 -jobs [get_param general.maxThreads]
wait_on_run synth_1
launch_runs impl_1 -to_step write_bitstream -jobs 12
wait_on_run impl_1
endsnippet

snippet build_sdk_project "generate sdk project"
# source /path/build_sdk.tcl

set project_path ${1:/home/wj/tmp}
set project_name ${2:scutimer}
set sdk_path $project_path/vivado/$project_name/${project_name}.sdk

set hdf_path [glob -directory $sdk_path *.hdf]
set hdf_name [lindex [split [file tail $hdf_path] .] 0]

set hw_name ${hdf_name}_hw_platform_0
set app_name ${3:main}
set bsp_name ${app_name}_bsp

setws $sdk_path

set files [glob -nocomplain -dir $sdk_path -type f -tails *]
foreach file $files {
    if {[string match -nocase {*.hdf} $file]} {
        continue
    }
    file delete [file join $sdk_path $file]
}

set dirs [glob -nocomplain -dir $sdk_path -type d -tails *]
foreach dir $dirs {
    file delete -force [file join $sdk_path $dir]
}

# 重复执行脚本时，需要deleteprojects
# deleteprojects -name $hw_name 
# deleteprojects -name $bsp_name 
# deleteprojects -name $app_name 

createhw -name $hw_name -hwspec $hdf_path

createbsp -name $bsp_name -hwproject $hw_name -proc ps7_cortexa9_0 -os standalone
# setlib -bsp $bsp_name -lib lwip202 -ver 1.2
# setlib -bsp $bsp_name -lib xilffs
# updatemss -mss $sdk_path/$bsp_name/system.mss
# regenbsp -bsp $bsp_name


createapp -name $app_name -hwproject $hw_name -bsp $bsp_name -proc ps7_cortexa9_0 -os standalone -lang C -app {Empty Application}
# file link -symbolic $sdk_path/$app_name/user_code $source_path 

# 导入已有文件
# importsources -name $app_name -path $sdk_path/$app_name/user_code

# configapp -app $app_name -add include-path $sdk_path/$app_name/user_code
endsnippet


snippet build_vitis_project "generate vivtis project"
# source /path/build_vitis.tcl
set script_path [ file dirname [ file normalize [ info script ] ] ]
set script_parent_path [ file dirname $script_path ]
set project_path $script_parent_path
set project_name main

set vitis_path $project_path/vivado/$project_name/${project_name}.vitis

set xsa_path [glob -directory $project_path/vivado/$project_name *.xsa]
set xsa_name [lindex [split [file tail $xsa_path] .] 0]

set platform_name ${xsa_name}_wrapper
set app_name main

if { [file exists $vitis_path] == 1 } {
    file delete -force $vitis_path
}

setws $vitis_path

platform create -name $platform_name -hw $xsa_path 

# -support-app {lwip_echo_server}, 自动添加lwip库
domain create -name {standalone_ps7_cortexa9_0} -display-name {standalone_ps7_cortexa9_0} -os {standalone} -proc {ps7_cortexa9_0} -runtime {cpp} -arch {32-bit} -support-app {lwip_echo_server}

# platform默认会创建2个domain, 所以要选择 
domain active standalone_ps7_cortexa9_0
platform generate

# app create -name lwip -template {lwIP Echo Server}
app create -name $app_name -template {Empty Application(C)}
# 不指定-platform <platform-name> 和-domain <domain-name> 时
# app create会自动使用当前active的platform和domain创建app

importsources -name $app_name -soft-link -path $project_path/source  -target-path source
app config -name $app_name include-path $project_path/source
endsnippet

snippet vio "create vio"
create_ip -name vio -vendor xilinx.com -library ip -version 3.0 -module_name vio_0
set_property -dict [list \
						 CONFIG.C_NUM_PROBE_IN {1}\
                         CONFIG.C_PROBE_IN0_WIDTH {128}\
						 CONFIG.C_PROBE_OUT0_WIDTH {1} CONFIG.C_PROBE_OUT0_INIT_VAL {0x0}\
						 CONFIG.C_PROBE_OUT1_WIDTH {16} CONFIG.C_PROBE_OUT1_INIT_VAL {0x0}\
						 CONFIG.C_PROBE_OUT2_WIDTH {32} CONFIG.C_PROBE_OUT2_INIT_VAL {0x0}\
						 CONFIG.C_NUM_PROBE_OUT {3} CONFIG.C_EN_PROBE_IN_ACTIVITY {0} ] [get_ips vio_0]
endsnippet

snippet ila "create ila"
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_${1:64}x${2:4096}
set_property -dict [list CONFIG.C_PROBE0_WIDTH {$1} CONFIG.C_DATA_DEPTH {$2} CONFIG.C_PROBE0_MU_CNT {3} CONFIG.ALL_PROBE_SAME_MU_CNT {3}] [get_ips ila_$1x$2]
endsnippet

snippet fifo "axi4-stream data fifo"
create_ip -name axis_data_fifo -vendor xilinx.com -library ip -version 2.0 -module_name fifo_sync_8x${1:512}
set_property -dict [list CONFIG.FIFO_DEPTH {$1} CONFIG.TDATA_NUM_BYTES {1} CONFIG.FIFO_MODE {2} CONFIG.HAS_TLAST {1} CONFIG.HAS_RD_DATA_COUNT {1}] [get_ips fifo_sync_8x$1]
endsnippet
